package com.health.platform.common.filter;


import com.alibaba.fastjson.JSON;
import com.health.platform.common.restful.AppResponse;
import com.health.platform.common.utils.token.ITokenValidate;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * <p>登录验证过滤器</p>
 * <p>创建日期：2021-02-07</p>
 *
 * @author zhou-qf
 */
@Component
@ConfigurationProperties(prefix = "auth")
@Data
@Slf4j
public class LoginFilter implements Filter {

    @Autowired
    private ITokenValidate tokenValidate;

    List<String> excludeUrls;

    private static final String OPTIONS_STR = "OPTIONS";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        // 跨域OPTIONS请求,登录请求直接放过
        if((OPTIONS_STR.equals(httpServletRequest.getMethod()))
                || (excludeUrls.contains((httpServletRequest.getRequestURI())))){
            chain.doFilter(request, response);
        }
        // 校验token是否存在
        else {
            if(tokenValidate.validate(httpServletRequest)){
                chain.doFilter(request, response);
                // 释放资源
                tokenValidate.release();
            } else{
                buildNoLogin(response);
            }
        }

    }

    @Override
    public void init(FilterConfig filterConfig){
        log.info("拦截器初始化成功");
    }

    @Override
    public void destroy() {
        log.info("拦截器注销成功");
    }

    /**
     * 设置未登录返回体
     * @param response response
     * @throws IOException IOException
     */
    private void buildNoLogin(ServletResponse response) throws IOException {
        HttpServletResponse httpServletResponse = (HttpServletResponse)response;
        OutputStream outputStream = response.getOutputStream();
        // 未登录code
        httpServletResponse.setStatus(401);
        httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
        httpServletResponse.setHeader("Access-Control-Allow-Headers", "*");
        // 未登录返回数据
        String data = JSON.toJSONString(AppResponse.noPermission("未登录"));
        byte[] dataByteArr = data.getBytes(StandardCharsets.UTF_8);
        // 返回前台
        outputStream.write(dataByteArr);
    }

}
